from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.core.paginator import Paginator
from django.db.models import Q, Count, Sum, Min, Max
from django.db import models
from datetime import datetime, timedelta, date
from main.models import User, Room, Booking, Bill, Feedback, Amenity
from functools import wraps
import os
import json


# 自定义管理员认证装饰器 - 基于浏览器cookie
def admin_required(view_func):
    """基于cookie的管理员权限验证装饰器"""
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        # 检查cookie中是否存在user_id
        user_id = request.COOKIES.get('user_id')
        if not user_id or not user_id.isdigit():
            messages.error(request, '请先登录')
            return redirect('user:user_login')
        
        try:
            # 获取用户并验证角色
            user = User.objects.get(id=int(user_id))
            if user.role != 'admin':
                messages.error(request, '您没有管理员权限')
                return redirect('user:dashboard')
            
            # 将用户对象存入request，方便后续使用
            request.user = user
            return view_func(request, *args, **kwargs)
        except User.DoesNotExist:
            # 用户不存在时清除cookie并重定向
            response = redirect('user:user_login')
            response.delete_cookie('user_id')
            response.delete_cookie('username')
            messages.error(request, '用户不存在或已被删除')
            return response
    return wrapper

# 替换原来的管理员权限测试函数和装饰器
# def is_admin(user):
#     return user.is_authenticated and user.role == 'admin'

# 使用自定义的admin_required装饰器
@admin_required
def dashboard(request):
    """管理员仪表板"""
    total_users = User.objects.filter(role='user').count()
    total_rooms = Room.objects.count()
    active_bookings = Booking.objects.filter(status__in=['confirmed', 'checked_in']).count()
    pending_feedbacks = Feedback.objects.filter(status='pending').count()
    
    # 获取最近预订
    recent_bookings = Booking.objects.select_related(
        'user', 'room'
    ).order_by('-created_at')[:5]
    
    return render(request, 'admin/dashboard.html', {
        'total_users': total_users,
        'total_rooms': total_rooms,
        'active_bookings': active_bookings,
        'pending_feedbacks': pending_feedbacks,
        'recent_bookings': recent_bookings
    })

# 将所有管理员视图的装饰器从@login_required和@user_passes_test改为@admin_required
@admin_required
def manage_rooms(request):
    """管理房间"""
    # 保留原有的房间管理逻辑
    PER_PAGE = 8
    
    keyword = request.GET.get('keyword', '').strip()
    price_range = request.GET.get('price_range', 'all')
    room_type = request.GET.get('room_type', 'all')
    
    query = Room.objects.all()
    
    # 关键词搜索
    if keyword:
        query = query.filter(Q(name__icontains=keyword) | Q(description__icontains=keyword))
    
    # 价格范围筛选
    if price_range == '0-200':
        query = query.filter(price__gte=0, price__lte=200)
    elif price_range == '200-500':
        query = query.filter(price__gte=200, price__lte=500)
    elif price_range == '500-1000':
        query = query.filter(price__gte=500, price__lte=1000)
    elif price_range == '1000+':
        query = query.filter(price__gte=1000)
    
    # 房间类型筛选
    if room_type != 'all':
        query = query.filter(room_type=room_type)
    
    query = query.order_by('-created_at')
    
    paginator = Paginator(query, PER_PAGE)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    
    search_params = {
        'keyword': keyword,
        'price_range': price_range,
        'room_type': room_type
    }
    
    return render(request, 'admin/rooms.html', {
        'rooms': page_obj,
        'search_params': search_params,
        'paginator': paginator,
        'page_obj': page_obj
    })


@admin_required
def manage_room(request, room_id=None):
    """添加/编辑房间"""
    room = None
    if room_id:
        room = get_object_or_404(Room, id=room_id)
    
    if request.method == 'POST':
        try:
            name = request.POST.get('name', '').strip()
            description = request.POST.get('description', '').strip()
            price = float(request.POST.get('price', 0))
            capacity = int(request.POST.get('capacity', 0))
            status = request.POST.get('status', 'available')
            size = float(request.POST.get('size', 0))
            room_type = request.POST.get('room_type', 'standard')
            room_number = request.POST.get('room_number', '').strip()
            
            if not all([name, price > 0, capacity > 0, size > 0, room_number]):
                messages.error(request, '所有必填字段必须填写且必须为正数')
                return redirect(request.path)
            
            # 处理图片上传
            image_url = None
            if 'image' in request.FILES:
                file = request.FILES['image']
                # 保存文件
                from django.core.files.storage import default_storage
                filename = default_storage.save(f'rooms/{file.name}', file)
                image_url = filename
            
            if room_id:
                # 编辑房间
                room.name = name
                room.description = description
                room.price = price
                room.capacity = capacity
                room.status = status
                room.size = size
                room.room_type = room_type
                room.room_number = room_number
                if image_url:
                    room.image_url = image_url
                room.save()
            else:
                # 添加新房间
                Room.objects.create(
                    name=name,
                    description=description,
                    price=price,
                    capacity=capacity,
                    status=status,
                    size=size,
                    room_type=room_type,
                    room_number=room_number,
                    image_url=image_url
                )
            
            messages.success(request, '房间信息已成功保存')
            return redirect('hotel_admin:manage_rooms')
        
        except Exception as e:
            messages.error(request, f'操作失败: {str(e)}')
    
    return render(request, 'admin/room_form.html', {'room': room})


@admin_required
def delete_room(request, room_id):
    """删除房间"""
    room = get_object_or_404(Room, id=room_id)
    
    # 检查是否有关联预订
    booking_count = Booking.objects.filter(room=room).count()
    if booking_count > 0:
        messages.error(request, f'无法删除:该房间仍有 {booking_count} 个关联预订')
    else:
        room.delete()
        messages.success(request, '房间已成功删除')
    
    return redirect('hotel_admin:manage_rooms')


@admin_required
def manage_bookings(request):
    """管理预订"""
    PER_PAGE = 10
    
    search_query = request.GET.get('search', '').strip()
    
    query = Booking.objects.select_related('user', 'room')
    
    if search_query:
        query = query.filter(
            Q(user__username__icontains=search_query) |
            Q(room__name__icontains=search_query) |
            Q(status__icontains=search_query)
        )
    
    query = query.order_by('-created_at')
    
    paginator = Paginator(query, PER_PAGE)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    
    return render(request, 'admin/bookings.html', {
        'bookings': page_obj,
        'search_query': search_query,
        'paginator': paginator,
        'page_obj': page_obj
    })


@admin_required
def update_booking_status(request, booking_id):
    """更新预订状态"""
    if request.method == 'POST':
        status = request.POST.get('status', '').lower().strip()
        booking = get_object_or_404(Booking, id=booking_id)
        
        if status in ['checked_out', 'cancelled']:
            # 退房或取消预订
            booking.delete()
            booking.room.status = 'available'
            booking.room.save()
            messages.success(request, '预订已删除,房间已恢复为可预订状态')
        else:
            booking.status = status
            booking.save()
            
            if status == 'checked_in':
                booking.room.status = 'occupied'
                booking.room.save()
                messages.success(request, '预订状态已更新为已入住,房间状态已同步')
            elif status == 'confirmed':
                booking.room.status = 'booked'
                booking.room.save()
                messages.success(request, '预订状态已更新为已确认,房间已标记为已预订')
    
    return redirect('hotel_admin:manage_bookings')


@admin_required
def manage_feedbacks(request):
    """管理反馈"""
    feedbacks = Feedback.objects.select_related('user').order_by('-created_at')
    
    return render(request, 'admin/feedbacks.html', {
        'feedbacks': feedbacks
    })


@admin_required
def update_feedback_status(request, feedback_id):
    """更新反馈状态"""
    if request.method == 'POST':
        status = request.POST.get('status')
        feedback = get_object_or_404(Feedback, id=feedback_id)
        
        feedback.status = status
        if status == 'resolved':
            feedback.updated_at = datetime.now()
        feedback.save()
        
        messages.success(request, '反馈状态已更新')
    
    return redirect('hotel_admin:manage_feedbacks')


@admin_required
def manage_bills(request):
    """管理账单"""
    bills = Bill.objects.select_related(
        'booking', 'booking__user', 'booking__room'
    ).order_by('-created_at')
    
    return render(request, 'admin/bills.html', {
        'bills': bills
    })


@admin_required
def update_bill_status(request, bill_id):
    """更新账单状态"""
    if request.method == 'POST':
        status = request.POST.get('status', '').lower().strip()
        bill = get_object_or_404(Bill, id=bill_id)
        
        if status == 'paid':
            bill.delete()
            messages.success(request, '已支付账单已删除')
        else:
            bill.status = status
            bill.save()
            messages.success(request, '账单状态已更新')
    
    return redirect('hotel_admin:manage_bills')


@admin_required
def delete_bill(request, bill_id):
    """删除账单"""
    bill = get_object_or_404(Bill, id=bill_id)
    bill.delete()
    messages.success(request, '账单已删除')
    
    return redirect('hotel_admin:manage_bills')


@admin_required
def reports(request):
    """报表"""
    try:
        # 获取最早和最晚的日期
        date_range = Booking.objects.exclude(status='cancelled').aggregate(
            min_date=models.Min('created_at'),
            max_date=models.Max('created_at')
        )
        
        if not date_range['min_date'] or not date_range['max_date']:
            end = datetime.now()
            start = end - timedelta(days=7)
        else:
            start = date_range['min_date']
            end = date_range['max_date']
        
        # 生成日期标签
        date_labels = []
        current_date = start.date()
        end_date = end.date()
        while current_date <= end_date:
            date_labels.append(current_date.strftime('%m-%d'))
            current_date += timedelta(days=1)
        
        # 生成图表数据(简化版本)
        chart_data = {
            'date_labels': date_labels,
            'occupancy_data': [60 + (i * 2) for i in range(len(date_labels))],
            'revenue_data': [5000 + (i * 500) for i in range(len(date_labels))],
            'room_type_data': [30, 15, 8, 5],
            'room_type_labels': ['标准间', '豪华间', '套房', '家庭房'],
            'utilization_data': [70, 60, 50, 40],
            'utilization_labels': ['标准间', '豪华间', '套房', '家庭房'],
            'overall_stats': {
                'avg_occupancy_rate': 75.0,
                'total_receivable': 50000,
                'avg_utilization_rate': 65.0,
                'total_bookings': 120,
                'occupancy_trend': 'up',
                'occupancy_change': 5.0,
                'receivable_trend': 'up',
                'receivable_change': 10.0,
                'utilization_trend': 'same',
                'utilization_change': 0,
                'bookings_trend': 'up',
                'bookings_change': 8.0
            }
        }
        
        return render(request, 'admin/echart.html', {
            'chart_data': chart_data,
            'error': None
        })
    
    except Exception as e:
        # 返回模拟数据
        chart_data = {
            'date_labels': ['01-01', '01-02', '01-03'],
            'occupancy_data': [60, 65, 70],
            'revenue_data': [5000, 6000, 7000],
            'room_type_data': [30, 15, 8, 5],
            'room_type_labels': ['标准间', '豪华间', '套房', '家庭房'],
            'utilization_data': [70, 60, 50, 40],
            'utilization_labels': ['标准间', '豪华间', '套房', '家庭房'],
            'overall_stats': {
                'avg_occupancy_rate': 65.0,
                'total_receivable': 18000,
                'avg_utilization_rate': 55.0,
                'total_bookings': 45,
                'occupancy_trend': 'up',
                'occupancy_change': 5.0,
                'receivable_trend': 'up',
                'receivable_change': 10.0,
                'utilization_trend': 'same',
                'utilization_change': 0,
                'bookings_trend': 'up',
                'bookings_change': 8.0
            }
        }
        
        return render(request, 'admin/echart.html', {
            'chart_data': chart_data,
            'error': f"数据库数据获取失败: {str(e)}"
        })


@admin_required
def system_operations(request):
    """系统运维页面"""
    return render(request, 'admin/system_ops.html')


@admin_required
def system_health(request):
    """获取系统健康状态"""
    import psutil
    
    health_data = {
        'cpu_percent': psutil.cpu_percent(interval=1),
        'memory_percent': psutil.virtual_memory().percent,
        'disk_percent': psutil.disk_usage('/').percent,
    }
    
    return JsonResponse({
        'success': True,
        'health': health_data
    })

